package cn.y.operation.framework.shiro;

import cn.y.operation.application.core.entity.SysUser;
import cn.y.operation.application.core.service.ISysMenuService;
import cn.y.operation.application.core.service.ISysRoleService;
import cn.y.operation.application.core.service.ISysUserService;
import cn.y.operation.framework.enums.ResponseMsgEnum;
import cn.y.operation.framework.enums.UserStatusEnum;
import cn.y.operation.framework.utils.encryption.MD5Utils;
import cn.y.operation.framework.utils.encryption.PasswordUtils;
import cn.y.operation.framework.utils.system.ShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Set;

public class UserRealm extends AuthorizingRealm {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private ISysUserService iSysUserService;
    @Resource
    private ISysRoleService iSysRoleService;
    @Resource
    private ISysMenuService iSysMenuService;

    /**
     * 认证信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authToken;
        String username = token.getUsername();
        String password;

        SysUser user;
        try {
            user = iSysUserService.loginUser(username);
            if (user == null) {
                throw new UnknownAccountException(ResponseMsgEnum.ACC_NOT_EXIST.getInfo());//用户不存在
            }
            if (user.getStatus() == null || !user.getStatus().equals(UserStatusEnum.USERNAME.getCode())) {
                throw new LockedAccountException(ResponseMsgEnum.ACCOUNT_LOCKED.getInfo());//非正常状态账号 被锁定
            }
            if (token.getPassword() == null) {
                throw new AuthenticationException(ResponseMsgEnum.PARAM_ERR.getInfo());//关键参数无效
            }
            password = PasswordUtils.encryptPassword(user.getSalt(), String.valueOf(token.getPassword()));
            token.setPassword(password.toCharArray());
            return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
        } catch (Exception e) {
            throw new AuthenticationException(e.getMessage());
        }
    }

    /**
     * 授权信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        if (!SecurityUtils.getSubject().isAuthenticated()) {
            doClearCache(principals);
            SecurityUtils.getSubject().logout();
            return null;
        }
        SysUser user = ShiroUtils.getSysUser();
        // 角色列表
        Set<String> roles;
        // 功能列表
        Set<String> menus;
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            info.addRole("admin");
            info.addStringPermission("*:*:*");
        } else {
            roles = iSysRoleService.selectRoleKeys(user.getUserId());
            menus = iSysMenuService.selectPermsByUserId(user.getUserId());
            // 角色加入AuthorizationInfo认证对象
            info.setRoles(roles);
            // 权限加入AuthorizationInfo认证对象
            info.setStringPermissions(menus);
        }
        return info;
    }

}
